package console.gui.osx;

import console.ANSIOutputBox;
import console.ClientGUI;
import console.ClientObserver;
import java.awt.Color;
import javax.swing.*;

/**
 *
 * @author Michael Hanns
 *
 */
public class ClientGUIImp extends javax.swing.JFrame implements ClientGUI {

    private static final long serialVersionUID = -3636482650592446191L;
    // Specific variables
    private double version;
    private ClientObserver console;
    private ANSIOutputBox cons;
    private boolean editorRunning;
    private editor.WITNAEditor editor;
    private transient java.awt.event.FocusListener focusl;

    /** Creates new form ClientGUIImp */
    public ClientGUIImp(ClientObserver parent, double softwareVersion) {
        this.version = softwareVersion;
        initComponents();
        cons = new ANSIOutputBox(outputBox);

        console = parent;
        editorRunning = false;
        setIconImage(new ImageIcon(getClass().getResource("/console/witnalogo.png")).getImage());
        inputBox.setSelectionColor(Color.ORANGE);
        inputBox.setSelectedTextColor(Color.BLACK);
        outputBox.setSelectionColor(Color.ORANGE);

        focusl = new java.awt.event.FocusAdapter() {

            @Override
            public void focusGained(java.awt.event.FocusEvent evt) {
                SwingUtilities.invokeLater(new Runnable() {

                    @Override
                    public void run() {
                        String command = "CHANNELHOST <channel name>";
                        inputBox.select(12, command.length());
                    }
                });
            }
        };
    }

    @Override
    public void clearInput() {
        inputBox.setText("");
    }

    @Override
    public void updateGUITerminal(String input) {
        cons.addANSIText(input);
    }

    @Override
    public void inputLine(String input) {
        console.sendToShell(input);
        clearInput();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        inputBox = new javax.swing.JFormattedTextField();
        inputSubmit = new javax.swing.JButton();
        outputBoxPane = new javax.swing.JScrollPane();
        outputBox = new javax.swing.JTextPane();
        menuBar = new javax.swing.JMenuBar();
        clientMenu = new javax.swing.JMenu();
        connectMenuItem = new javax.swing.JMenuItem();
        hostMenu = new javax.swing.JMenu();
        hostServerMenuItem = new javax.swing.JMenuItem();
        hostChannelMenuItem = new javax.swing.JMenuItem();
        jSeparator1 = new javax.swing.JPopupMenu.Separator();
        disconnectMenuItem = new javax.swing.JMenuItem();
        quitMenuItem = new javax.swing.JMenuItem();
        editMenu = new javax.swing.JMenu();
        launchEditorMenuItem = new javax.swing.JMenuItem();
        viewMenu = new javax.swing.JMenu();
        fontMenu = new javax.swing.JMenu();
        incFontSizeMenuItem = new javax.swing.JMenuItem();
        decFontSizeMenuItem = new javax.swing.JMenuItem();
        jSeparator2 = new javax.swing.JPopupMenu.Separator();
        clearScreenMenuItem = new javax.swing.JMenuItem();
        helpMenu = new javax.swing.JMenu();
        helpMenuItem = new javax.swing.JMenuItem();
        aboutMenuItem = new javax.swing.JMenuItem();
        jSeparator3 = new javax.swing.JPopupMenu.Separator();
        updatesItem = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("WITNA v" + version);
        setMinimumSize(new java.awt.Dimension(725, 420));

        inputBox.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.LOWERED));
        inputBox.setFont(new java.awt.Font("Courier New", 0, 12));
        inputBox.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
                inputBoxFocusLost(evt);
            }
        });
        inputBox.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                inputBoxKeyPressed(evt);
            }
        });

        inputSubmit.setText("Submit");
        inputSubmit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                inputSubmitActionPerformed(evt);
            }
        });

        outputBox.setBackground(new java.awt.Color(0, 0, 0));
        outputBox.setContentType("text/rtf");
        outputBox.setEditable(false);
        outputBox.setFont(new java.awt.Font("Courier New", 1, 14)); // NOI18N
        outputBox.setForeground(new java.awt.Color(204, 204, 204));
        outputBoxPane.setViewportView(outputBox);

        clientMenu.setText("Client");

        connectMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_C, java.awt.event.InputEvent.ALT_MASK));
        connectMenuItem.setMnemonic('C');
        connectMenuItem.setText("Connect");
        connectMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                connectMenuItemActionPerformed(evt);
            }
        });
        clientMenu.add(connectMenuItem);

        hostMenu.setMnemonic('H');
        hostMenu.setText("Host...");

        hostServerMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_H, java.awt.event.InputEvent.ALT_MASK));
        hostServerMenuItem.setMnemonic('S');
        hostServerMenuItem.setText("Server");
        hostServerMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                hostServerMenuItemActionPerformed(evt);
            }
        });
        hostMenu.add(hostServerMenuItem);

        hostChannelMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_H, java.awt.event.InputEvent.CTRL_MASK));
        hostChannelMenuItem.setMnemonic('H');
        hostChannelMenuItem.setText("Channel");
        hostChannelMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                hostChannelMenuItemActionPerformed(evt);
            }
        });
        hostMenu.add(hostChannelMenuItem);

        clientMenu.add(hostMenu);
        clientMenu.add(jSeparator1);

        disconnectMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_D, java.awt.event.InputEvent.META_MASK));
        disconnectMenuItem.setMnemonic('D');
        disconnectMenuItem.setText("Disconnect");
        disconnectMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                disconnectMenuItemActionPerformed(evt);
            }
        });
        clientMenu.add(disconnectMenuItem);

        quitMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_Q, java.awt.event.InputEvent.META_MASK));
        quitMenuItem.setText("Quit");
        quitMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                quitMenuItemActionPerformed(evt);
            }
        });
        clientMenu.add(quitMenuItem);

        menuBar.add(clientMenu);

        editMenu.setText("Edit");

        launchEditorMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_E, java.awt.event.InputEvent.META_MASK));
        launchEditorMenuItem.setMnemonic('E');
        launchEditorMenuItem.setText("Launch Editor");
        launchEditorMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                launchEditorMenuItemActionPerformed(evt);
            }
        });
        editMenu.add(launchEditorMenuItem);

        menuBar.add(editMenu);

        viewMenu.setText("View");

        fontMenu.setText("Font...");

        incFontSizeMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_EQUALS, java.awt.event.InputEvent.META_MASK));
        incFontSizeMenuItem.setText("Increase font size");
        incFontSizeMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                incFontSizeMenuItemActionPerformed(evt);
            }
        });
        fontMenu.add(incFontSizeMenuItem);

        decFontSizeMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_MINUS, java.awt.event.InputEvent.META_MASK));
        decFontSizeMenuItem.setText("Decrease font size");
        decFontSizeMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                decFontSizeMenuItemActionPerformed(evt);
            }
        });
        fontMenu.add(decFontSizeMenuItem);

        viewMenu.add(fontMenu);
        viewMenu.add(jSeparator2);

        clearScreenMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_K, java.awt.event.InputEvent.META_MASK));
        clearScreenMenuItem.setText("Clear screen");
        clearScreenMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                clearScreenMenuItemActionPerformed(evt);
            }
        });
        viewMenu.add(clearScreenMenuItem);

        menuBar.add(viewMenu);

        helpMenu.setText("Help");

        helpMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_PERIOD, java.awt.event.InputEvent.META_MASK));
        helpMenuItem.setText("Help");
        helpMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                helpMenuItemActionPerformed(evt);
            }
        });
        helpMenu.add(helpMenuItem);

        aboutMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_A, java.awt.event.InputEvent.ALT_MASK));
        aboutMenuItem.setText("About");
        aboutMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                aboutMenuItemActionPerformed(evt);
            }
        });
        helpMenu.add(aboutMenuItem);
        helpMenu.add(jSeparator3);

        updatesItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_U, java.awt.event.InputEvent.META_MASK));
        updatesItem.setText("Check for updates..");
        updatesItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                updatesItemActionPerformed(evt);
            }
        });
        helpMenu.add(updatesItem);

        menuBar.add(helpMenu);

        setJMenuBar(menuBar);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(outputBoxPane, javax.swing.GroupLayout.DEFAULT_SIZE, 702, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(inputBox, javax.swing.GroupLayout.DEFAULT_SIZE, 604, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(inputSubmit, javax.swing.GroupLayout.PREFERRED_SIZE, 91, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(outputBoxPane, javax.swing.GroupLayout.DEFAULT_SIZE, 452, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(inputBox, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(inputSubmit, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void inputBoxKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_inputBoxKeyPressed
        switch (evt.getKeyCode()) {
            case 38:
                inputBox.setText(console.getHistory(true));
                break;
            case 40:
                inputBox.setText(console.getHistory(false));
                break;
            case 10:
                inputLine(inputBox.getText());
                break;
        }
    }//GEN-LAST:event_inputBoxKeyPressed

    private void inputSubmitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_inputSubmitActionPerformed
        inputLine(inputBox.getText());
    }//GEN-LAST:event_inputSubmitActionPerformed

    private void hostServerMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_hostServerMenuItemActionPerformed
        ServerHostDialog newDialog = new ServerHostDialog(this, true, console);
        newDialog.setVisible(true);
    }//GEN-LAST:event_hostServerMenuItemActionPerformed

    private void quitMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_quitMenuItemActionPerformed
        if (editorRunning) {
            editor.setVisible(false);
        }
        console.sendToShell("quit");
        System.exit(0);
    }//GEN-LAST:event_quitMenuItemActionPerformed

    private void disconnectMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_disconnectMenuItemActionPerformed
        inputLine("disconnect");
    }//GEN-LAST:event_disconnectMenuItemActionPerformed

    private void launchEditorMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_launchEditorMenuItemActionPerformed
        updateGUITerminal("\nLaunching editor..\n");
        if (!editorRunning) {
            editorRunning = true;
            if (editor == null) {
                editor = new editor.osx.WITNAFrameView(false, version);
            }
            editor.setVisible(true);
            editor.addWindowListener(new java.awt.event.WindowAdapter() {

                @Override
                public void windowClosed(java.awt.event.WindowEvent e) {
                    editorRunning = false;
                }
            });
        } else {
            updateGUITerminal("You are already running WITNA Editor!\n");
        }
    }//GEN-LAST:event_launchEditorMenuItemActionPerformed

    private void hostChannelMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_hostChannelMenuItemActionPerformed
        String command = "CHANNELHOST <channel name>";
        inputBox.setText(command);
        inputBox.select(12, command.length());
        inputBox.addFocusListener(focusl);
    }//GEN-LAST:event_hostChannelMenuItemActionPerformed

    private void inputBoxFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_inputBoxFocusLost
        inputBox.removeFocusListener(focusl);
    }//GEN-LAST:event_inputBoxFocusLost

    private void clearScreenMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_clearScreenMenuItemActionPerformed
        outputBox.setText("");
    }//GEN-LAST:event_clearScreenMenuItemActionPerformed

    private void connectMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_connectMenuItemActionPerformed
        new ServerBrowser(this, false, console).setVisible(true);
    }//GEN-LAST:event_connectMenuItemActionPerformed

    private void aboutMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_aboutMenuItemActionPerformed
        new About(this, false, version).setVisible(true);
    }//GEN-LAST:event_aboutMenuItemActionPerformed

    private void incFontSizeMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_incFontSizeMenuItemActionPerformed
        cons.updateFontSize(true);
    }//GEN-LAST:event_incFontSizeMenuItemActionPerformed

    private void decFontSizeMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_decFontSizeMenuItemActionPerformed
        cons.updateFontSize(false);
    }//GEN-LAST:event_decFontSizeMenuItemActionPerformed

    private void helpMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_helpMenuItemActionPerformed
        console.sendToShell("help");
    }//GEN-LAST:event_helpMenuItemActionPerformed

    private void updatesItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_updatesItemActionPerformed
        new CheckForUpdates(this, false, version).setVisible(true);
    }//GEN-LAST:event_updatesItemActionPerformed
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JMenuItem aboutMenuItem;
    private javax.swing.JMenuItem clearScreenMenuItem;
    private javax.swing.JMenu clientMenu;
    private javax.swing.JMenuItem connectMenuItem;
    private javax.swing.JMenuItem decFontSizeMenuItem;
    private javax.swing.JMenuItem disconnectMenuItem;
    private javax.swing.JMenu editMenu;
    private javax.swing.JMenu fontMenu;
    private javax.swing.JMenu helpMenu;
    private javax.swing.JMenuItem helpMenuItem;
    private javax.swing.JMenuItem hostChannelMenuItem;
    private javax.swing.JMenu hostMenu;
    private javax.swing.JMenuItem hostServerMenuItem;
    private javax.swing.JMenuItem incFontSizeMenuItem;
    private javax.swing.JFormattedTextField inputBox;
    private javax.swing.JButton inputSubmit;
    private javax.swing.JPopupMenu.Separator jSeparator1;
    private javax.swing.JPopupMenu.Separator jSeparator2;
    private javax.swing.JPopupMenu.Separator jSeparator3;
    private javax.swing.JMenuItem launchEditorMenuItem;
    private javax.swing.JMenuBar menuBar;
    private javax.swing.JTextPane outputBox;
    private javax.swing.JScrollPane outputBoxPane;
    private javax.swing.JMenuItem quitMenuItem;
    private javax.swing.JMenuItem updatesItem;
    private javax.swing.JMenu viewMenu;
    // End of variables declaration//GEN-END:variables
}
